package com.etung.iot.demo.services.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etung.iot.demo.alarm.AlarmCacheUtil;
import com.etung.iot.demo.boxConfig.Box;
import com.etung.iot.demo.boxConfig.StorageSetting;
import com.etung.iot.demo.dao.*;
import com.etung.iot.demo.handler.UserCacheUtil;
import com.etung.iot.demo.modles.*;
import com.etung.iot.demo.services.BoxConfigService;
import com.etung.iot.demo.storage.ConStorageSelector;
import com.etung.iot.demo.storage.conTriggerStorage.PreConditionStorageUtil;
import com.etung.iot.demo.storage.constorage.ConditionStorageUtil;
import com.etung.iot.demo.storage.StorageRuleUtil;
import com.etung.iot.demo.vo.req.BoxConfigReq;
import com.etung.iot.demo.vo.req.ProjectReq;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
public class BoxConfigServiceImpl implements BoxConfigService {

    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private PortMapper portMapper;
    @Autowired
    private VariantMapper variantMapper;
    @Autowired
    private AlarmMapper alarmMapper;
    @Autowired
    private BoxMapper boxMapper;
    @Autowired
    private BoxConfigMapper  boxConfigMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private StorageMapper storageMapper;
    @Autowired
    private StorageRuleUtil storageRuleUtil;
    @Autowired
    private UserCacheUtil userCacheUtil;
    @Autowired
    private AlarmCacheUtil alarmCacheUtil;
    @Autowired
    private ConditionStorageMapper conditionStorageMapper;
    @Autowired
    private ConditionStorageUtil conditionStorageUtil;
    @Autowired
    private ConStorageSelector conStorageSelector;
    @Autowired
    private PreConditionStorageUtil preConditionStorageUtil;

    @Transactional
    @Override
    public void saveConfig(Box box) {
        String imei = box.getImei();
        //先删除原有的配置
        boxMapper.delete(new QueryWrapper<BoxEntity>().eq("imei",imei));
        portMapper.delete(new QueryWrapper<PortEntity>().eq("imei",imei));
        deviceMapper.delete(new QueryWrapper<DeviceEntity>().eq("imei",imei));
        variantMapper.delete(new QueryWrapper<VariantEntity>().eq("imei",imei));
        alarmMapper.delete(new QueryWrapper<AlarmEntity>().eq("imei",imei));
        storageMapper.delete(new QueryWrapper<StorageEntity>().eq("imei",imei));
        conditionStorageMapper.delete(new QueryWrapper<ConditionStorageEntity>().eq("imei",imei));
        BoxEntity boxEntity = new BoxEntity();
        boxEntity.setImei(imei).setBoxName(box.getBoxName()).setFirmware(box.getFirmware()).setModel(box.getModel()).setReal(box.getIsReal());
        boxEntity.setProjectId(box.getProjectId());
        boxMapper.insert(boxEntity);
        if(box.getPortList()!= null){
            box.getPortList().forEach(port -> {
                PortEntity portEntity = new PortEntity();
                portEntity.setImei(imei).setPortId(port.getPortId()).setType(port.getType()).setPortName(port.getPortName()).setBitMax(port.getBitMax());
                portEntity.setWordMax(port.getWordMax()).setTimeout(port.getTimeout()).setRecoveryInterval(port.getRecoveryInterval()).setInterval(port.getInterval());
                portEntity.setRetryTimes(port.getRetryTimes()).setIp(port.getIp()).setMask(port.getMask()).setGateway(port.getGateway());
                portEntity.setDns(port.getDns()).setMac(port.getMac()).setBrand(port.getBrand()).setModel(port.getModel());
                portEntity.setBaud(port.getBaud()).setParity(port.getParity()).setDataBit(port.getDataBit()).setStopBit(port.getStopBit());
                portMapper.insert(portEntity);

                if(port.getDeviceList() != null){
                    port.getDeviceList().forEach(device -> {
                        DeviceEntity deviceEntity = new DeviceEntity();
                        deviceEntity.setImei(imei).setPortId(port.getPortId()).setDeviceId(device.getDeviceId());
                        deviceEntity.setName(device.getName()).setBrand(device.getBrand()).setModel(device.getModel()).setBitMax(device.getBitMax());
                        deviceEntity.setWordMax(device.getWordMax()).setTimeout(device.getTimeout()).setRecoveryInterval(device.getRecoveryInterval()).setInterval(device.getInterval());
                        deviceEntity.setRetryTimes(device.getRetryTimes()).setIp(device.getIp()).setPort(device.getPort());
                        if(device.getProperties() != null){
                            deviceEntity.setProperties(JSON.toJSONString(device.getProperties()));
                        }
                        deviceMapper.insert(deviceEntity);
                        if(device.getVariantList() != null){
                            device.getVariantList().forEach(variant -> {
                                VariantEntity variantEntity = new VariantEntity();
                                variantEntity.setImei(imei).setPortId(port.getPortId()).setDeviceId(device.getDeviceId()).setVarId(variant.getVarId());
                                variantEntity.setName(variant.getVarName()).setAddressType(variant.getAddressType()).setDataType(variant.getDataType()).setReadWrite(variant.getReadWriteable());
                                variantEntity.setNote(variant.getVarDesc()).setUnit(variant.getUnit()).setOffset(variant.getOffset());
                                variantEntity.setAddressType2(variant.getAddressType2()).setOffset2(variant.getOffset2());
                                if(variant.getLinearSetting() != null){
                                    variantEntity.setIsLinear(variant.getLinearSetting().getIsLinear()?1:0);
                                    variantEntity.setInMin(variant.getLinearSetting().getInMin()).setInMax(variant.getLinearSetting().getInMax());
                                    variantEntity.setOutMin(variant.getLinearSetting().getOutMin()).setOutMax(variant.getLinearSetting().getOutMax());
                                    variantEntity.setLinearDataType(variant.getLinearSetting().getDataType());
                                }else{
                                    variantEntity.setIsLinear(0);
                                }
                                variantMapper.insert(variantEntity);

                                if(variant.getAlarmList() != null){
                                    variant.getAlarmList().forEach(alarm -> {
                                        AlarmEntity alarmEntity = new AlarmEntity();
                                        alarmEntity.setImei(imei).setPortId(port.getPortId()).setDeviceId(device.getDeviceId()).setVarId(variant.getVarId()).setAlarmId(alarm.getAlarmId());
                                        alarmEntity.setType(alarm.getAlarmType()).setRuleExp(alarm.getAlarmExp()).setTip(alarm.getTip());
                                        alarmMapper.insert(alarmEntity);
                                    });
                                }
                                if (variant.getStorageSetting() != null){
                                    StorageSetting storageSetting = variant.getStorageSetting();
                                    StorageEntity storageEntity = new StorageEntity();
                                    storageEntity.setImei(imei).setPortId(port.getPortId()).setDeviceId(device.getDeviceId()).setVarId(variant.getVarId());
                                    storageEntity.setType(storageSetting.getType()).setSamplingPeriod(storageSetting.getSamplingPeriod());
                                    storageEntity.setUpLimit(storageSetting.getUpLimit()).setLowerLimit(storageSetting.getLowerLimit());
                                    storageEntity.setConditionRule(storageSetting.getConditionRule());
                                    storageMapper.insert(storageEntity);
                                }
                            });
                        }
                    });
                }
            });
        }
        //条件存储处理
        if (box.getConditionStorageList() != null && box.getConditionStorageList().size() >0){
            box.getConditionStorageList().forEach(conditionStorage -> {
                ConditionStorageEntity conditionStorageEntity = new ConditionStorageEntity();
                BeanUtils.copyProperties(conditionStorage,conditionStorageEntity);
                conditionStorageEntity.setImei(box.getImei());
                conditionStorageMapper.insert(conditionStorageEntity);
            });
        }

        storageRuleUtil.removeStorageRule(imei);
        userCacheUtil.removeUserId(imei);
        alarmCacheUtil.removeAlarmCache(imei);
//        conditionStorageUtil.removeConditionStorageRule(imei);
        conStorageSelector.removeConditionStorageRule(imei);
        preConditionStorageUtil.loadChangeTypeList();
    }

    @Override
    public void saveFile(BoxConfigReq boxConfig) {
        BoxConfig config = new BoxConfig();
        config.setConfigSetting(boxConfig.getConfigSetting());
        config.setCreateTime(new Date());
        config.setUserId(boxConfig.getId());
        config.setProjectId(boxConfig.getProjectId());
        boxConfigMapper.insert(config);
    }

    @Override
    public String selectByUser(ProjectReq project) {
        BoxConfig boxConfig = boxConfigMapper.selectOne(
                new QueryWrapper<BoxConfig>()
                        .eq("user_id", project.getId())
                        .eq("project_id",project.getProjectId())
                        .orderByDesc("create_time").last("limit 1"));
        if(boxConfig == null){
            throw new RuntimeException("当前用户没有配置文件");
        }
        return boxConfig.getConfigSetting();
    }


}
